package hotel.callback.oversea.task;

import hotel.base.oversea.utils.*;
import hotel.callback.oversea.config.service.RedisService;
import hotel.base.oversea.constant.CommonConstants;
import hotel.base.oversea.constant.MeituanConstants;
import hotel.base.oversea.constant.enums.MtGoodsEnums;
import hotel.base.oversea.vo.BatchPushRoomDatasVo;
import hotel.base.oversea.vo.RoomDataEntityVO;
import hotel.base.oversea.vo.RoomPriceVo;
import hotel.base.oversea.vo.RoomStatusInventory;
import hotel.base.oversea.vo.meituan.request.goods.MtHotelGoodsBaseInfoVo;
import hotel.base.oversea.vo.meituan.request.goods.MtHotelGoodsChildInfoVo;
import hotel.base.oversea.vo.meituan.request.goods.MtHotelGoodsVo;
import hotel.callback.oversea.service.MtHotelGoodsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;


@Slf4j
@Component
public class MeituanCheckOneHotelGoodsDataTask {
    private String timestamp = "mcohgdt"+String.valueOf(System.currentTimeMillis());
    @Autowired
    private RedisService redisService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private MtHotelGoodsService mtHotelGoodsService;
    private void setTimestamp(String timestamp){
        this.timestamp = timestamp;
    }

    @Async("threadPoolRp")
    public void executeCheckTenHotelGoods(List<Long> hotelIds,Integer days,String timestamp){
        redisService.setUnit("AllTimeQueryCheckPriceAndStatusJob_task_doing",1,1L, TimeUnit.MINUTES);
        //log.info("MeituanSaveApiLogTask executeCheckTenHotelGoods{} >>>>>>>>> 异步线程 保存系统日志  开始执行时间：{}",timestamp,DateUtil.getNowTime());
        setTimestamp(timestamp);
        log.info("executeCheckTenHotelGoods酒店ids={}",hotelIds);
        //时间参数  开始时间  结束时间   10 天 暂定
        Date nowDate = new Date();
        //String thisDateStartYmd = DateUtil.formatDate(DateUtil.addDay(startTimeYmdhms,-1),"yyyy-MM-dd");//上送昨天查询第一天为昨天
        String nowHourStr = DateUtil.formatDate(nowDate,"HH");
        String today = DateUtil.formatDate(nowDate,"yyyy-MM-dd");
        String yestoday = DateUtil.formatDate(DateUtil.addDay(nowDate,-1),"yyyy-MM-dd");
        String startDateRoomStatusYmd = DateUtil.formatDate(nowDate,"yyyy-MM-dd");
        String nowStr = DateUtil.formatDate(nowDate,"yyyy-MM-dd HH");
        if(Integer.valueOf(nowStr.split(" ")[1])<6){
            startDateRoomStatusYmd = DateUtil.getFontsDay(startDateRoomStatusYmd);
            days += 1;
        }

        Map<String,List<Integer>> allHotelAboutAllGoodsId = new HashMap<>();//key = 酒店id   value = 该酒店对应的产品id集合
        LinkedHashMap<String,List<RoomPriceVo>> oneHotelGroupGoodsListMap = new LinkedHashMap<>();//key=price_酒店id_goodsId  value='某一个酒店的某一个产品'的所有日期价格集合
        LinkedHashMap<String,List<RoomStatusInventory>> oneHotelGroupGoodsStatusListMap = new LinkedHashMap<>();//key=status_酒店id_goodsId  value='某一个酒店的某一个产品'的所有日期房态集合
        for (int i = 0; i < days; i++) {

            //主动查询Rp产品接口，接口包含房态和价格
            String thisDateEndYmd = DateUtil.formatDate(DateUtil.addDay(startDateRoomStatusYmd,1),"yyyy-MM-dd");
            log.info("executeCheckTenHotelGoods {} 调用接口前，thisDateStartYmd={}，thisDateEndYmd={},hotelIds={}",timestamp,startDateRoomStatusYmd,thisDateEndYmd,hotelIds);
            Result<Object> result = mtHotelGoodsService.getMtHotelGoods(hotelIds,startDateRoomStatusYmd,thisDateEndYmd, MtGoodsEnums.roomDateTypeEnum.DAY.getCode());
            //log.info("MeituanCheckOneHotelGoodsDataTask hotelIds={},result={}",GsonUtils.GsonString(hotelIds),GsonUtils.GsonString(result));
            if(result.getCode()== CommonConstants.SUCCESS){

                MtHotelGoodsVo res_oneDateHotelGoods = JacksonUtil.objToBean(result.getData(), MtHotelGoodsVo.class);
                List<MtHotelGoodsChildInfoVo> res_oneDateManyHotelGoodsData = res_oneDateHotelGoods.getHotelGoods();
                //log.info("{} 请求成功：res_oneDateManyHotelGoodsData.size={}",timestamp,res_oneDateManyHotelGoodsData.size());
                if(null != res_oneDateManyHotelGoodsData && res_oneDateManyHotelGoodsData.size()>0){
                    int k = 0;
                    for (MtHotelGoodsChildInfoVo res_oneHotelOneDateAllGoods:res_oneDateManyHotelGoodsData){
                        //log.info("{} 当前某一天批次酒店遍历 k={},thisDateStartYmd={},hotelid={}",timestamp,k,thisDateStartYmd,res_oneHotelOneDateAllGoods.getHotelId());
                        Integer thisHotelId = res_oneHotelOneDateAllGoods.getHotelId();
                       /* Boolean existSaleHotel = redisService.isMember(CommonConstants.SWITCH_SALE_HOTEL_TO_PRICE_LIST,thisHotelId);
                        if(existSaleHotel){
                            log.info("MeituanCheckOneHotelGoodsDataTask 不是上架酒店 thisHotelId={}",thisHotelId);
                            continue;
                        }*/
                        //携程接口参数对象vo
                        Long thisTimestamp = System.currentTimeMillis();
                        log.info("allHotelAboutAllGoodsId存在，222thisTimestamp={}",thisTimestamp);
                        String thisTimestampApi = StringUtil.getTimestampRandom(thisTimestamp).toString()+String.valueOf(thisHotelId).substring(0,4)+String.valueOf(40);
                        //log.info("{} 解析酒店={},thisHotelAllOneDateGoods.size={}",timestamp,thisHotelId);
                        List<MtHotelGoodsBaseInfoVo> thisHotelAllOneDateGoods =res_oneHotelOneDateAllGoods.getGoods();
                        if(null != thisHotelAllOneDateGoods && thisHotelAllOneDateGoods.size()>0){
                            //log.info("{} 解析酒店={},thisHotelAllOneDateGoods.size={}",timestamp,thisHotelId,thisHotelAllOneDateGoods.size());
                            for (MtHotelGoodsBaseInfoVo info:thisHotelAllOneDateGoods) {
                                Integer thisGoodsId = Integer.valueOf(info.getGoodsId());
                                String key = String.valueOf(thisHotelId)+"_"+String.valueOf(thisGoodsId);
                                Integer put = 0;
                                //查询出的是该酒店所有的产品 不一定为我们上架的产品需要做判断
                                String existSale = null;//(String)redisService.get(CommonConstants.SWITCH_SELLING_THE_HOUSE_TYPE+String.valueOf(thisHotelId)+"_"+String.valueOf(thisGoodsId));

                                existSale = (String)redisService.hmGet(CommonConstants.SWITCH_SELLING_THE_HOUSE_TYPE,thisHotelId+"_"+thisGoodsId);
                                if(!ObjectUtils.isEmpty(existSale)){
                                    //log.info("MeituanCheckOneHotelGoodsDataTask 进入第二版 判断上架产品：thisGoodsId={},existSale={}",thisGoodsId,existSale);
                                }else{
                                    existSale = (String)redisService.get(CommonConstants.SWITCH_SELLING_THE_HOUSE_TYPE+thisHotelId+"_"+thisGoodsId);
                                    //log.info("MeituanCheckOneHotelGoodsDataTask 进入第一版 判断上架产品：thisGoodsId={},existSale={}",thisGoodsId,existSale);
                                }

                                if(null != existSale){
                                    log.info("MeituanCheckOneHotelGoodsDataTask existSale={}",existSale);
                                    //log.info("价格，为我们上架产品，继续后续判断");
                                    //1、构建携程-价格日期集合
                                    /*if(null != info.getPriceModels() && info.getPriceModels().size()>0){
                                        MtHotelGoodsPriceBaseDetailVo price = info.getPriceModels().get(0);//每次只查一天，所以priceModels的size=1
                                        Boolean isChangePrice = mtHotelGoodsService.checkMtGoodsChange(String.valueOf(thisHotelId),thisGoodsId,startDateRoomStatusYmd,price.getSalePrice(),"room_price","1");
                                        if(isChangePrice){
                                            put=1;
                                            RoomPriceVo priceVo = new RoomPriceVo();
                                            priceVo.setDate(startDateRoomStatusYmd);
                                            priceVo.setSalePrice(price.getSalePrice());
                                            priceVo.setSubPrice(price.getSubPrice());
                                            log.info("24小时主动查询校验存在变化{}，一个产品一个日期价格发生变化价格产品信息为{}",timestamp,key+"_"+startDateRoomStatusYmd+"_"+price.getSalePrice()+",");
                                            //该产品该日期的价格发送改变
                                            List<RoomPriceVo> oneHotelOneGoodsOneDatePriceData = null;
                                            if (null != oneHotelGroupGoodsListMap.get("price_" + thisHotelId + "_" + info.getGoodsId())) {
                                                oneHotelOneGoodsOneDatePriceData = oneHotelGroupGoodsListMap.get("price_" + thisHotelId + "_" + info.getGoodsId());
                                            } else {
                                                oneHotelOneGoodsOneDatePriceData = new ArrayList<>();
                                            }
                                            oneHotelOneGoodsOneDatePriceData.add(priceVo);
                                            oneHotelGroupGoodsListMap.put("price_" + thisHotelId + "_" + info.getGoodsId(), oneHotelOneGoodsOneDatePriceData);
                                        }
                                    }*/


                                    //2、构建携程-房态日期集合

                                    Integer status = info.getGoodsStatus();

                                    //5天变成售卖4天
                                    String closeThisDateRedis = (String)redisService.get("normal_close_this_date");//yyyy-MM-dd
                                    if(!ObjectUtils.isEmpty(closeThisDateRedis)){
                                        if(closeThisDateRedis.equals(startDateRoomStatusYmd)){
                                            log.info("RP NORMAL 减少天售卖，从后递减 hotelId={},goodsId={},closeThisDateRedis={},date={},state={}",thisHotelId,thisGoodsId,closeThisDateRedis,startDateRoomStatusYmd,status);
                                            status = 0;
                                        }
                                    }

                                    Boolean isChange = mtHotelGoodsService.checkMtGoodsChange(today,nowHourStr,yestoday,String.valueOf(thisHotelId),thisGoodsId,startDateRoomStatusYmd,status,"room_status","1",null,thisTimestampApi);
                                    if(isChange){
                                        put=1;
                                        RoomStatusInventory statusVo = new RoomStatusInventory();
                                        statusVo.setDate(startDateRoomStatusYmd);
                                        statusVo.setGoodStatus(status);
                                        log.info("校验返回存在房态变化{}，一个产品一个日期价格发生变化房态产品信息为{}",timestamp,key+"_"+startDateRoomStatusYmd+"_"+status+",");
                                        //该产品该日期的状态发送改变，重构数据
                                        List<RoomStatusInventory> oneHotelOneGoodsOneDateStatusData = null;
                                        if (null != oneHotelGroupGoodsStatusListMap.get("status_" + thisHotelId + "_" + info.getGoodsId())) {
                                            oneHotelOneGoodsOneDateStatusData = oneHotelGroupGoodsStatusListMap.get("status_" + thisHotelId + "_" + info.getGoodsId());
                                        } else {
                                            oneHotelOneGoodsOneDateStatusData = new ArrayList<>();
                                        }
                                        oneHotelOneGoodsOneDateStatusData.add(statusVo);
                                        oneHotelGroupGoodsStatusListMap.put("status_" + thisHotelId + "_" + info.getGoodsId(), oneHotelOneGoodsOneDateStatusData);

                                    }

                                    //3、临时参数  酒店id集合map
                                    if(put==1){
                                        List<Integer> thisHotelAboutGoods = null;
                                        if (null != allHotelAboutAllGoodsId.get(thisHotelId+"_"+thisTimestampApi)) {
                                            thisHotelAboutGoods = allHotelAboutAllGoodsId.get(thisHotelId+"_"+thisTimestampApi);
                                        } else {
                                            thisHotelAboutGoods = new ArrayList<>();
                                        }
                                        thisHotelAboutGoods.add(thisGoodsId);
                                        allHotelAboutAllGoodsId.put(thisHotelId+"_"+thisTimestampApi, thisHotelAboutGoods);
                                    }
                                }
                            }
                        }
                        k++;
                    }
                    //log.info("{} 当前处理完一个日期，一批酒店starttime={}，房态size={},价格map={}，当前酒店产品ids={}", timestamp,thisDateStartYmd, oneHotelGroupGoodsStatusListMap.size(),oneHotelGroupGoodsListMap.size(),allHotelAboutAllGoodsId.size());
                }
            }else{
                log.error("{} executeCheckTenHotelGoods 调用产品列表接口失败：",timestamp, GsonUtils.GsonString(result));
            }
            startDateRoomStatusYmd = thisDateEndYmd;
        }
        //log.info("{},allHotelAboutAllGoodsId={},oneHotelGroupGoodsListMap长度={}",timestamp,GsonUtils.GsonString(allHotelAboutAllGoodsId),oneHotelGroupGoodsListMap.size());
        if(null != allHotelAboutAllGoodsId && allHotelAboutAllGoodsId.size()>0){
            log.info("allHotelAboutAllGoodsId存在allHotelAboutAllGoodsId={}",GsonUtils.GsonString(allHotelAboutAllGoodsId));
            for (Map.Entry oneHotel:allHotelAboutAllGoodsId.entrySet()){

                //遍历酒店
                String thisHotelIdAndTimetampApi = (String)oneHotel.getKey();
                Integer thisHotelId = Integer.valueOf(thisHotelIdAndTimetampApi.split("_")[0]);
                String thisTimestampApi = thisHotelIdAndTimetampApi.split("_")[1];
                List<Integer> thisHotelGoodsIds = (List<Integer>)oneHotel.getValue();
                log.info("allHotelAboutAllGoodsId存在，111酒店={},thisHotelIdAndTimetampApi={}",thisHotelId,thisHotelIdAndTimetampApi);

                BatchPushRoomDatasVo oneHotelVoSwitchsApi = new BatchPushRoomDatasVo();
                oneHotelVoSwitchsApi.setMtHotelId(thisHotelId);
                oneHotelVoSwitchsApi.setTimestamp(thisTimestampApi);
                List<RoomDataEntityVO> oneGoodsVoAboutPriceStatusListData= new ArrayList<>();
                log.info("allHotelAboutAllGoodsId存在，oneGoodsVoAboutPriceStatusListData,thisHotelIdAndTimetampApi={},thisHotelId={},thisHotelGoodsIds={}",thisHotelIdAndTimetampApi,thisHotelId,GsonUtils.GsonString(thisHotelGoodsIds));
                for (Integer goodsId:thisHotelGoodsIds){
                    //携程接口参数   RoomDataEntityVO
                    RoomDataEntityVO oneGoodsVoAboutPriceStatus = new RoomDataEntityVO();
                    oneGoodsVoAboutPriceStatus.setGoodId(goodsId);

                    //一个产品，获取到对应的价格集合和房态集合
                    List<RoomPriceVo> priceData = oneHotelGroupGoodsListMap.get("price_"+thisHotelId+"_"+goodsId);
                    List<RoomStatusInventory> statusData = oneHotelGroupGoodsStatusListMap.get("status_"+thisHotelId+"_"+goodsId);
                    int put = 0;
                    if(null != priceData && priceData.size()>0){
                        oneGoodsVoAboutPriceStatus.setRoomPrices(priceData);
                        put = 1;
                    }
                    if(null != statusData && statusData.size()>0){
                        oneGoodsVoAboutPriceStatus.setRoomStatusInventorys(statusData);
                        put = 1;
                    }

                    //当前酒店 追加 产品
                    if(put==1){
                        oneGoodsVoAboutPriceStatusListData.add(oneGoodsVoAboutPriceStatus);
                    }
                }

                //结束便利产品构建数据，当前酒店的所有产品set
                oneHotelVoSwitchsApi.setRoomDataEntityList(oneGoodsVoAboutPriceStatusListData);
                //结束构建携程接口参数对象vo，，push到队列缓存中

//                if(null == redisTemplate.opsForValue().get("query_mt_pri_info_about_push_data_show")){//输出日志太多了，但是为了可以排查数据，做间隔输出
//                    log.info("{} push到缓存队列存在变动的房态产品{}，主动变动房态时间戳为{},主动变动房态推送数据为{} ",timestamp,thisTimestampApi,thisHotelId,GsonUtils.GsonString(oneHotelVoSwitchsApi));
//                    redisTemplate.opsForValue().set("query_mt_pri_info_about_push_data_show",1,15,TimeUnit.MINUTES);
//                }else{
//                    log.info("{} push到缓存队列存在变动的房态产品，主动变动房态时间戳为{},主动变动房态酒店为{}",timestamp,thisTimestampApi,thisHotelId);
//                }

                String pushvalue= GsonUtils.GsonString(oneHotelVoSwitchsApi);//最新需要push的json窜
                //加入队列，每次一个酒店数据
                log.info("该酒店Rp查询push到队列thisHotelIdAndTimetampApi={},hotelid={},pushvalue={}",thisHotelIdAndTimetampApi,thisHotelId,pushvalue);
                pushQueueRpPriceAndStatus(pushvalue);
//                if(null == redisTemplate.opsForValue().get(CallbackConstants.REDIS_KEY_NOT_CHECK_FOR_RP)){
//                    SendUtils.dingMsgNotLogByReturn("【很好办-RP定时器价格房态-变更】",hotel.base.oversea.utils.DateUtil.getCurrTime()+"：时间戳="+oneHotelVoSwitchsApi.getTimestamp()+"，酒店id："+oneHotelVoSwitchsApi.getMtHotelId()+",内容："+ GsonUtils.GsonString(oneHotelVoSwitchsApi.getRoomDataEntityList()),2,restTemplate);;
//                   // SendUtils.dingMsgNotLog("【很好办-24小时查询价格+房态RP-变更】",hotel.base.oversea.utils.DateUtil.getCurrTime()+"：时间戳="+oneHotelVoSwitchsApi.getTimestamp()+"，酒店id："+oneHotelVoSwitchsApi.getMtHotelId()+",内容："+ GsonUtils.GsonString(oneHotelVoSwitchsApi.getRoomDataEntityList()),2,restTemplate);
//                }else{
//                    SendUtils.dingMsgNotLogByReturn("【很好办-RP定时器价格房态-变更】",hotel.base.oversea.utils.DateUtil.getCurrTime()+"：时间戳="+oneHotelVoSwitchsApi.getTimestamp()+"，酒店id："+oneHotelVoSwitchsApi.getMtHotelId()+",内容：当前为程序不做重复判断，Rp定时器轮询上架酒店直推产品价格和房态给携程，未来10天",2,restTemplate);
//                   // SendUtils.dingMsgNotLog("【很好办-24小时查询价格+房态RP-变更】",hotel.base.oversea.utils.DateUtil.getCurrTime()+"：时间戳="+oneHotelVoSwitchsApi.getTimestamp()+"，酒店id："+oneHotelVoSwitchsApi.getMtHotelId()+",内容：当前为程序不做重复判断，轮询所有上架酒店直推所有产品价格和房态给携程",2,restTemplate);
//                }
//                MtNotifyShortLog mtNotifyShortLog = new MtNotifyShortLog();
//                mtNotifyShortLog.setId(StringUtil.getUUID()+thisHotelId);
//                mtNotifyShortLog.setTimestamp(thisTimestampApi);
//                mtNotifyShortLog.setCreateTime(new Date());
//                mtNotifyShortLog.setMtHotelId(String.valueOf(thisHotelId));
//                mtNotifyShortLog.setSwHotelId(null);
//                mtNotifyShortLog.setOprate(MtGoodsEnums.goodsChangeType.PUSH.getCode());//push
//                mtNotifyShortLog.setSource(40);//10 异步价格  11 主动查询价格 20 异步房态  21 主动查询房态 30 携程推送成功数据   40  主动查询价格+房态
//                try{
//                    mtNotifyShortLogMapper.insert(mtNotifyShortLog);
//                }catch (Exception e){
//                    log.error("主动查询有变化价格房态数据保存日志mtNotifyShortLog异常{},{}",GsonUtils.GsonString(mtNotifyShortLog),e.getMessage());
//                    e.printStackTrace();
//                }

            }

        }




        ///log.info("MeituanSaveApiLogTask executeCheckTenHotelGoods {} >>>>>>>>> 异步线程 保存系统日志  执行结束时间：{}",timestamp,DateUtil.getNowTime());


    }

    public void pushQueueRpPriceAndStatus(String pushvalue){

        //1、加入队列，推给携程
        redisTemplate.opsForList().leftPush(MeituanConstants.REDIS_CHANGE_GOODS_DATA_MANY_HOTEL, pushvalue);
    }

}
